<?php
class ExpenseUtility {

	private static $_errorMessage = '';

	public static function getMessage() {
		return self::$_errorMessage;
	}

	private function __construct() {}

	/**
	 * add Expense
	 * @return new expenseId
	*/
	public static function addExpense( $postVars ){
		$loginUsrId = Login::checkLoginStatus() == Login::USER_LOGGED_IN ? Login::getUserInfo( 'userId' ) : 0;
		if( $loginUsrId <= 0 ){
			throw new Exception( 'Your login session expired, Please login first!' );
		}
		try{
			// check teamid is numeric value
			$teamId = trim( $postVars[ 'teamId' ] );
			if( !is_numeric( $teamId ) && $teamId > 0 ){
				throw new Exception( 'teamId is a required parameter !' );
			}
			// check members array
			$teamMembers = isset( $postVars[ 'members' ] ) ? $postVars[ 'members' ] : array();
			if( count( $teamMembers ) <= 0 ){
				throw new Exception( 'Members is a required parameter !' );
			}
			// check spendByMemberId is numeric value
			$spendByMemberId = trim( $postVars[ 'spendBy' ] );
			if( !is_numeric( $spendByMemberId ) && $spendByMemberId > 0 ){
				throw new Exception( 'spendBy is a required parameter !' );
			}
			// check description is empty
			$description = trim( $postVars[ 'description' ] );
			if( $description == '' ){
				throw new Exception( 'Expense detail is a required parameter !' );
			}
			// check money is numeric value
			$money = round( trim( $postVars[ 'money' ] ), 2 );
			if( !is_numeric( $money ) && $money > 0 ){
				throw new Exception( 'money is a required parameter !' );
			}
			// process selected part of expense members their groups team and calculate the amount each
			$groupData = self::processTeamMembersData( $teamId, $teamMembers, $spendByMemberId, $money );
			$groupId = trim( $groupData[ 'groupId' ] );
			if( !is_numeric( $groupId ) ){
				throw new Exception( 'groupId is a required parameter !' );
			}
			$expenseGroupMembers = $groupData[ 'expenseGroupMembers' ];
			$partOfExpense = $groupData[ 'partOfExpense' ];
			$calculatedMoney = round( $groupData[ 'calculatedMoney' ], 2 );
			if( !is_numeric( $calculatedMoney ) && $calculatedMoney > 0 ){
				throw new Exception( 'calculative money is a required parameter !' );
			}
			
			$expenseDate = date( 'Y-m-d' );
			$yearMonth = date( 'Ym' );
			$yearWeek = date( 'YW' );
			// add expense data
			$objExpenseAdd = getDb( 'expense', 'add' );
			$objExpenseAdd->set( "description||$description", "teamId||$teamId", 
				"groupId||$groupId", "groupMemberId||$spendByMemberId",
				"expenseGroupMembers||$expenseGroupMembers", "partOfExpense||$partOfExpense", 
				"money||$calculatedMoney", "actualMoney||$money", "expenseDate||$expenseDate", 
				"expenseYearMonth||$yearMonth", "expenseYearWeek||$yearWeek" );
			$newTeamId = $objExpenseAdd->getLastInsertedId();
			if( $newTeamId < 1 ){
				throw new Exception( 'Unable to add expense data!' );
			}
		}catch( Exception $ex ){
			throw $ex;
		}
	}

	/**
	 * Remove Entry from table
	 * @param $expenseId
	 * @return true/false
	*/
	public function removeExpenseData( $expenseId ){
		try{
			throw new Exception( "Remove feature is under testing stage, Please try some other time." );
			
			// check if login session live or not
			$loginUsrId = Login::checkLoginStatus() == Login::USER_LOGGED_IN ? Login::getUserInfo( 'userId' ) : 0;
			if( $loginUsrId <= 0 ){
				throw new Exception( 'Your login session expired, Please login first!' );
			}
			// check if expense id is a valid numeric value or not
			if( !is_numeric( $expenseId ) || $expenseId <= 0 ){
				throw new Exception( "Invalid parameter supplied !" );
			}
			// check for expense entry 
			$objExpense = getMultiple( 'expense', "expenseId||$expenseId", "groupMemberId||$loginUsrId" );
			if( $objExpense->getResultCount() <= 0 ){
				throw new Exception( "No Entry found in table " );
			}
			$teamId = $objExpense->getTeamId();
			$groupId = $objExpense->getGroupId();
			$groupMemberId = $objExpense->getGroupMemberId();
			$expenseGroupMembers = $objExpense->getExpenseGroupMembers();
			$partOfExpense = $objExpense->getPartOfExpense();
			$money = $objExpense->getMoney();
			$actualMoney = $objExpense->getActualMoney();
			describe( 'removeExpenseData', true );

		}catch( Exception $ex ){
			throw $ex;
		}
	}

	/**
	 * Process the team members
	 * check each member is part of team
	 * check if spendByMemberId is part of the expendature or not then process moeny
	 * create group
	 * @return array
	*/
	public function processTeamMembersData( $teamId, $teamMembers, $spendByMemberId, $money ){
		try{
			if( !is_numeric( $teamId ) || !is_numeric( $spendByMemberId ) || !is_numeric( $money ) || !is_array( $teamMembers ) ){
				throw new Exception( "Invalid Request !" );
			}
			if( $teamId == 0 || $spendByMemberId == 0 || $money == 0 || count( $teamMembers ) == 0 ){
				throw new Exception( "Invalid Request !" );
			}
			// check team members active or not also check each member verified or not 
			self::checkMembersAndTeam( $teamId, $teamMembers, $spendByMemberId );
			// team group id
			$result = array();
			// check if money spend by is part of expense if yet then process else do some calculation
			if( isset( $teamMembers[ $spendByMemberId ] ) ){
				// sort array acending order
				asort( $teamMembers );
				// make array as a string
				$membersStr = implode( ',', $teamMembers );
				// add or edit team members groups data
				self::calculateTeamExpenseData( $teamId, $teamMembers, $spendByMemberId, $money );
				$groupId = self::saveTeamGroupData( $teamId, $teamMembers, $spendByMemberId, $money );
				// make final array
				$result = array( 'groupId' => $groupId, 'expenseGroupMembers' => $membersStr,
				'partOfExpense' => 'Y', 'calculatedMoney' => $money );
			}else{
				#money spend by user is not part of the expense so here need some calculation
				#and add the amount accordingly so user get his/her actual amount back
				#code yet to written
				$totalMembers = count( $teamMembers );
				$calculatedShareAmount = ( $money/$totalMembers );
				$calculatedMoney = $money + $calculatedShareAmount;
				$teamMembers[ $spendByMemberId ] = $spendByMemberId;
				// sort array acending order
				asort( $teamMembers );
				// make array as a string
				$membersStr = implode( ',', $teamMembers );
				self::calculateTeamExpenseData( $teamId, $teamMembers, $spendByMemberId, $calculatedMoney );
				$groupId = self::saveTeamGroupData( $teamId, $teamMembers, $spendByMemberId, $calculatedMoney );
				// make final array
				$result = array( 'groupId' => $groupId, 'expenseGroupMembers' => $membersStr,
				'partOfExpense' => 'N', 'calculatedMoney' => $calculatedMoney );
			}
			return $result;
		}catch( Exception $ex ){
			throw $ex;
		}
	}

	/**
	 * @param $teamId, $teamMembers, $spendByMemberId
	 * Check teamid existance in table
	 * check each member is part of team
	 * create group
	 * @return true
	*/
	public static function checkMembersAndTeam( $teamId, $teamMembers, $spendByMemberId ){
		// check if expense spend by user is part of the team or not 
		$teamMemberChkObj = getMultiple( 'teamMember', "userId||$spendByMemberId", 
			"teamId||$teamId", 'status||active', 'joined||Y', 'count||Y' );
		if( $teamMemberChkObj->getTotalCount() == 0 ){
			throw new Exception( "You can't add this expense as amout spend by member is not active or joined team yet !" );
		}
		// check if expense spend by user is verified
		$userChkObj = getMultiple( 'user', "userId||$spendByMemberId", 'status||verified', 'count||Y' );
		if( $userChkObj->getTotalCount() == 0 ){
			throw new Exception( "You can't add this expense spend by member is not verified user !" );
		}
		// check if members is part of the team or not
		foreach( $teamMembers as $member ){
			if( !is_numeric( $member ) || $member <= 0 ){
				throw new Exception( "Invalid Member Selection !" );
			}
			// check if member is verified
			$objTeamMemberChk = getMultiple( 'teamMember', "userId||$member", 
				"teamId||$teamId", 'status||active', 'joined||Y', 'count||Y' );
			if( $objTeamMemberChk->getTotalCount() == 0 ){
				throw new Exception( "You can't add this expense as one of selected member is not active or joined team yet !" );
			}
			// check if member is verified
			$objUserChk = getMultiple( 'user', "userId||$member", 'status||verified', 'count||Y' );
			if( $objUserChk->getTotalCount() == 0 ){
				throw new Exception( "You can't add this expense as one of selected member is not verified user !" );
			}
		}
		return true;
	}

	/**
	 * @param $teamId, $teamMembers, $spendByMemberId, $money
	 * add/edit group and calculate each amount for each group members
	 * special calculation for those who is not part of expense item but he/she pay the money
	 * @return groupId
	*/
	public static function saveTeamGroupData( $teamId, $teamMembers, $spendByMemberId, $money ){
		try{
			$groupId = 0;
			// sort members acending order and this step is most important for the flow of expense 
			asort( $teamMembers );
			$totalMembers = count( $teamMembers );
			if( $totalMembers <= 1 ){
				return false;
			}
			// make array as a string
			$membersStr = implode( ',', $teamMembers );
			// check if group exist or not else create the team group
			$objTeamGroupChk = getMultiple( 'group', "members||$membersStr", 
				"membersCount||$totalMembers", "teamId||$teamId" );
			if( $objTeamGroupChk->getResultCount() > 0 ){
				if( $objTeamGroupChk->getStatus() == 'inactive' ){
					throw new Exception( "Selected Members's group is inactive, Please contact team owner about this issue !" );
				}
				$groupId = $objTeamGroupChk->getGroupId();
				// calculate total share divied with each members
				$calculatedSharedAmount = round( ( $money/$totalMembers ), 2 );
				$spendByCalculatedSharedAmount = $calculatedSharedAmount;
				if( isset( $teamMembers[ $spendByMemberId ] ) ){
					$spendByCalculatedSharedAmount = round( ( $money - $calculatedSharedAmount ), 2 );
				}
				foreach( $teamMembers as $member ){
					// check if user spend money then it is PLUS else it becomes MINUS
					$operator = $member == $spendByMemberId ? 'plus' : 'minus';
					$formattedAmount = $member == $spendByMemberId ? $spendByCalculatedSharedAmount : $calculatedSharedAmount;
					// edit group members with calculative amount
					$objGroupMember = getMultiple( 'groupMember', "teamId||$teamId", 
						"groupId||$groupId", "userId||$member" );
					// get previous amount
					$dbAmount = $objGroupMember->getMoney();
					// get previous operator
					$dbOperator = $objGroupMember->getOperator();
					if( $operator == 'plus' ){ // current expense is plus means he/she will take money from others
						if( $dbOperator == 'plus' ){// previous expense is plus means he/she will take money from others
							$calculatedAmount = round( ( $formattedAmount + $dbAmount ), 2 );
						}else{ // previous expense is minus means he/she will give money to others
							$calculatedAmount = round( ( $formattedAmount - $dbAmount ), 2 );
							if( $calculatedAmount < 0 ){// new calculative expense is minus means he/she will give money to others
								$operator = 'minus';
								$calculatedAmount = str_replace( '-', '', $calculatedAmount );
							}
						}
					}else{ // current expense is minus means he/she will give money to other
						if( $dbOperator == 'plus' ){// previous expense is plus means he/she will take money from others
							$calculatedAmount = round( ( $dbAmount - $formattedAmount ), 2 );
							if( $calculatedAmount > 0 ){// new calculative expense is plus means he/she will take money from others
								$operator = 'plus';
							}
						}else{// new calculative expense is plus means he/she will give money to other
							$calculatedAmount = round( ( $formattedAmount + $dbAmount ), 2 );
						}
					}
					$calculatedAmount = $calculatedAmount < 0 ? str_replace( '-', '', $calculatedAmount ) : $calculatedAmount;
					if( $calculatedAmount == 0 ){
						$operator = 'plus';
					}
					// update group member record
					$objGroupMember->get( 0 )->update( 'money||' . round( $calculatedAmount, 2 ), "operator||$operator" );
				}
			}else{
				$memberNames = array();
				# add group and group members
				foreach( $teamMembers as $member ){
					$memberNames[ $member ] = getMultiple( 'user', "userId||$member" )->getName();
				}
				$groupName = implode( ',', $memberNames );
				$objTeamGroupAdd = getDb( 'group', 'add' );
				$objTeamGroupAdd->set( "title||$groupName", "members||$membersStr", 
					"membersCount||$totalMembers", "teamId||$teamId" );
				$groupId = $objTeamGroupAdd->getLastInsertedId();
				if( $groupId <= 0 ){
					throw new Exception( "Unable to add selected members groups, Please try later or contact team owner !" );
				}
				// calculate total share divied with each members
				$calculatedSharedAmount = round( ( $money/$totalMembers ), 2 );
				$spendByCalculatedSharedAmount = $calculatedSharedAmount;
				if( isset( $teamMembers[ $spendByMemberId ] ) ){
					$spendByCalculatedSharedAmount = round( ( $money - $calculatedSharedAmount ), 2 );
				}
				foreach( $teamMembers as $member ){
					// check if user spend money then it is PLUS else it becomes MINUS
					$operator = $member == $spendByMemberId ? 'plus' : 'minus';
					$formattedAmount = $member == $spendByMemberId ? $spendByCalculatedSharedAmount : $calculatedSharedAmount;
					// add group members with calculative amount
					$objGroupMemberAdd = getDb( 'groupMember', 'add' );
					$objGroupMemberAdd->set( "teamId||$teamId", "groupId||$groupId", 
						"userId||$member", "money||$formattedAmount", 
						"operator||$operator" );
				}
			}
			return $groupId;
		}catch( Exception $ex ){
			throw $ex;
		}
	}

	/**
	 * @param $teamId, $teamMembers, $spendByMemberId, $money
	 * add/edit team and calculate each amount for each team members
	 * special calculation for those who is not part of expense item but he/she pay the money
	 * @return true/false
	*/
	public static function calculateTeamExpenseData( $teamId, $teamMembers, $spendByMemberId, $money ){
		try{
			$totalMembers = count( $teamMembers );
			if( $totalMembers <= 1 ){
				return false;
			}
			// calculate total share divied with each members
			$calculatedSharedAmount = round( ( $money/$totalMembers ) );
			$spendByCalculatedSharedAmount = $calculatedSharedAmount;
			if( isset( $teamMembers[ $spendByMemberId ] ) ){
				$spendByCalculatedSharedAmount = round( $money - $calculatedSharedAmount );
			}
			foreach( $teamMembers as $member ){
				// check if user spend money then it is PLUS else it becomes MINUS
				$operator = $member == $spendByMemberId ? 'plus' : 'minus';
				$formattedAmount = $member == $spendByMemberId ? $spendByCalculatedSharedAmount : $calculatedSharedAmount;
				// edit team members with calculative amount
				$objTeamMember = getMultiple( 'teamMember', "teamId||$teamId", "userId||$member" );
				if( $objTeamMember->getResultCount() > 0 ){
					// get previous amount
					$dbAmount = round( $objTeamMember->getMoney(), 2 );
					// get previous operator
					$dbOperator = $objTeamMember->getOperator();

					if( $operator == 'plus' ){ // current expense is plus means he/she will take money from others
						if( $dbOperator == 'plus' ){// previous expense is plus means he/she will take money from others
							$calculatedAmount = round( ( $formattedAmount + $dbAmount ), 2 );
						}else{ // previous expense is minus means he/she will give money to others
							$calculatedAmount = round( ( $formattedAmount - $dbAmount ), 2 );
							if( $calculatedAmount < 0 ){// new calculative expense is minus means he/she will give money to others
								$operator = 'minus';
								$calculatedAmount = str_replace( '-', '', $calculatedAmount );
							}
						}
					}else{ // current expense is minus means he/she will give money to other
						if( $dbOperator == 'plus' ){// previous expense is plus means he/she will take money from others
							$calculatedAmount = round( ( $dbAmount - $formattedAmount ), 2 );
							if( $calculatedAmount > 0 ){// new calculative expense is plus means he/she will take money from others
								$operator = 'plus';
							}
						}else{// new calculative expense is plus means he/she will give money to other
							$calculatedAmount = round( ( $formattedAmount + $dbAmount ), 2 );
						}
					}
					
					$calculatedAmount = $calculatedAmount < 0 ? str_replace( '-', '', $calculatedAmount ) : $calculatedAmount;
					if( $calculatedAmount == 0 ){
						$operator = 'plus';
					}
					// update team member record
					$objTeamMember->get( 0 )->update( 'money||' . round( $calculatedAmount, 2 ), "operator||$operator" );
				}
			}
			return true;
		}catch( Exception $ex ){
			throw $ex;
		}
	}

	/**
	 * get the all groups
	 * @return array
	*/
	public static function getExpenses( $teamId, $yearMonth, $pageNumber=1, $quantity=5 ){
		$loginUsrId = Login::checkLoginStatus() == Login::USER_LOGGED_IN ? Login::getUserInfo( 'userId' ) : 0;
		if( $loginUsrId <= 0 ){
			throw new Exception( 'Your login session expired, Please login first!' );
		}
		$filters = array();
		$whereClause = array( "quantity||$quantity", "pageNumber||$pageNumber", 'paging||Y' );
		if( $teamId > 0 && is_numeric( $teamId ) ){
			$whereClause[] = "teamId||$teamId";
			$filters[] = "tid/$teamId";
		}
		if( $yearMonth > 0 && is_numeric( $yearMonth ) ){
			$whereClause[] = "expenseYearMonth||$yearMonth";
			$filters[] = "ym/$yearMonth";
		}
		$expenses = array();
		try{
			$objExpenses = getMultiple( 'expense', $whereClause );
			foreach( $objExpenses() as $i => $objExpense ){
				$id = $objExpense->getExpenseId();
				$team = getSingle( 'team', $objExpense->getTeamId() )->getTitle();
				$group = getSingle( 'group', $objExpense->getGroupId() )->getTitle();
				$creator = getSingle( 'user', $objExpense->getGroupMemberId() )->getName();

				$canDelete = $objExpense->getGroupMemberId() == $loginUsrId ? true : false;

				$moeny = round( $objExpense->getMoney(), 2 );
				// check if money spent by team member is not part of the expense 
				// then show his/her original amount spend and also stop showing his/her from group expense column 
				if( $objExpense->getPartOfExpense() == 'N' ){
					$group = str_replace( $creator . ',', '', $group );
					$group = str_replace(  ',' . $creator, '', $group );
					$moeny = round( $objExpense->getActualMoney(), 2 );
				}
				// fill the final arry
				$expenses[] = array(
					'id' => $id, 'desc' => $objExpense->getDescription(), 
					'status' => ucwords( $objExpense->getStatus() ), 
					'money' => 'Rs. ' . $moeny . '/-', 'canDelete' => $canDelete,
					'shortDesc' => getShortText( $objExpense->getDescription(), 30 ),
					'team' => $team, 'group' => $group, 'creator' => $creator,
					'date' => date( "d, M Y", strtotime( $objExpense->getExpenseDate() ) )
				);
			}
			/* Paging area  */
			$paging = array();
			$latestPages = $objExpenses->getPaging( 'expenses/nv/page/');
			$countPages = count( $latestPages );
			for( $i = 0; $i < $countPages; $i++ ) {
				$paging[$i]['number'] = $latestPages[$i]['numbers'];
				$paging[$i]['class'] =  $latestPages[$i]['isActive'] ? 'active' : 'inactive';
				$paging[$i]['link'] = $latestPages[$i]['link'] ? $latestPages[$i]['link'] .( count( $filters ) > 0 ? implode( '/', $filters ) . '/' : '' ) : '';
			}
			return array( 'expenses' => $expenses, 'paging' => $paging );
		}catch( Exception $ex ){
			throw $ex;
		}
	}

	/**
	 * get the all groups
	 * @return array
	*/
	public static function getTeamReport( $teamId ){
		$loginUsrId = Login::checkLoginStatus() == Login::USER_LOGGED_IN ? Login::getUserInfo( 'userId' ) : 0;
		if( $loginUsrId <= 0 ){
			throw new Exception( 'Your login session expired, Please login first!' );
		}
		$report = array();
		try{
			$objTeam = getMultiple( 'team', "teamId||$teamId" );
			if( $objTeam->getResultCount() == 0 ){
				return $report;
			}
			$objTeamMembers = getMultiple( 'teamMember', "teamId||$teamId", 'quantity||500' );
			foreach( $objTeamMembers() as $i => $objTeamMember ){
				$userId = $objTeamMember->getUserId();
				$objUser = getSingle( 'user', $userId );
				if( $objUser->getResultCount() == 0 ){
					continue;
				}
				$report[] = array(
					'user' => $objUser->getName(), 
					'operator' => $objTeamMember->getOperator() == 'plus' ? '' : '-',
					'money' => round( $objTeamMember->getMoney(), 2 ) . '/-'
				);
			}
			return $report;
		}catch( Exception $ex ){
			throw $ex;
		}
	}

	/**
	 * get team expenses report
	 * @return array
	*/
	public static function getTeamExpensesReport( $params, $pageNumber=1, $quantity=30 ){
		$loginUsrId = Login::checkLoginStatus() == Login::USER_LOGGED_IN ? Login::getUserInfo( 'userId' ) : 0;
		if( $loginUsrId <= 0 ){
			throw new Exception( 'Your login session expired, Please login first!' );
		}

		$teamExpenses = array(
			'groupId' => 0, 'memberId' => 0,
			'expenses' => array(), 'paging' => array()
		);
		$expenses = $teamExpenses[ 'expenses' ];
		$groupId = $teamExpenses[ 'groupId' ];
		$memberId = $teamExpenses[ 'memberId' ];
		$paging = $teamExpenses[ 'paging' ];

		$teamId = $params[ 'teamId' ];
		$members = $params[ 'members' ];
		$memberId = $params[ 'memberId' ];
		$groupId = $params[ 'groupId' ];
		$month = $params[ 'month' ];
		$year = $params[ 'year' ];


		//describe( $params );

		$filters = array();
		$whereClause = array( 'status||active', 'processed||N' );
		if( $teamId > 0 && is_numeric( $teamId ) ){
			$whereClause[] = "teamId||$teamId";
			$filters[] = "tid/$teamId";
		}else{
			return $teamExpenses;
		}
		if( $month > 0 && is_numeric( $month ) && $year > 0 && is_numeric( $year ) ){
			$yearMonth = $month < 10 ? $year . "0$month" : $year . $month;
			$whereClause[] = "expenseYearMonth||$yearMonth";
			$filters[] = "m/$month";
			$filters[] = "y/$year";
		}else{
			return $teamExpenses;
		}

		if( count( $members ) == 1 ){
			$memberId = current( $members );
			$whereClause[] = "groupMemberId||$memberId";
			$filters[] = "uid/$memberId";
			$teamExpenses[ 'memberId' ] = $memberId;
		}elseif( count( $members ) > 1 ){
			// make array as a string
			$membersStr = implode( ',', $members );
			$totalMembers = count( $members );
			// check if group exist or not else create the team group
			$objTeamGroupChk = getMultiple( 'group', "members||$membersStr", 
				"membersCount||$totalMembers", "teamId||$teamId", 'status||active' );
			if( $objTeamGroupChk->getResultCount() <= 0 ){
				return $teamExpenses;
			}
			$groupId = $objTeamGroupChk->getGroupId();
			$whereClause[] = "groupId||$groupId";
			$filters[] = "gid/$groupId";
			$teamExpenses[ 'groupId' ] = $groupId;
		}elseif( $groupId > 0 ){
			$objTeamGroupChk = getMultiple( 'group', 'status||active', 
				"groupId||$groupId", "teamId||$teamId" );
			if( $objTeamGroupChk->getResultCount() <= 0 ){
				return $teamExpenses;
			}
			$whereClause[] = "groupId||$groupId";
			$filters[] = "gid/$groupId";
			$teamExpenses[ 'groupId' ] = $groupId;
		}elseif( $memberId > 0 ){
			$objTeamMemberChk = getMultiple( 'teamMember', 'status||active', 
				"userId||$memberId", "teamId||$teamId" );
			if( $objTeamMemberChk->getResultCount() <= 0 ){
				return $teamExpenses;
			}
			$whereClause[] = "groupMemberId||$memberId";
			$filters[] = "uid/$memberId";
			$teamExpenses[ 'memberId' ] = $memberId;
		}else{
			return $teamExpenses;
		}

		//describe( $whereClause, true );
		$whereClause1 = $whereClause;
		$whereClause[] = "quantity||$quantity";
		$whereClause[] = "pageNumber||$pageNumber";
		$whereClause[] = "paging||Y";
		$expenses = array();
		try{
			$objExpenses = getMultiple( 'expense', $whereClause );
			foreach( $objExpenses() as $i => $objExpense ){
				$id = $objExpense->getExpenseId();
				$team = getSingle( 'team', $objExpense->getTeamId() )->getTitle();
				$group = getSingle( 'group', $objExpense->getGroupId() )->getTitle();
				$creator = getSingle( 'user', $objExpense->getGroupMemberId() )->getName();
				$moeny = round( $objExpense->getMoney(), 2 );
				// check if money spent by team member is not part of the expense 
				// then show his/her original amount spend and also stop showing his/her from group expense column 
				if( $objExpense->getPartOfExpense() == 'N' ){
					$group = str_replace( $creator . ',', '', $group );
					$group = str_replace(  ',' . $creator, '', $group );
					$moeny = round( $objExpense->getActualMoney(), 2 );
				}
				// fill the final arry
				$expenses[] = array(
					'id' => $id, 'desc' => $objExpense->getDescription(), 
					'status' => ucwords( $objExpense->getStatus() ), 
					'money' => 'Rs. ' . $moeny . '/-',
					'shortDesc' => getShortText( $objExpense->getDescription(), 30 ),
					'team' => $team, 'group' => $group, 'creator' => $creator,
					'date' => date( "d, M Y", strtotime( $objExpense->getExpenseDate() ) )
				);
			}
			if( $objExpenses->getResultCount() > 0 ){
				$totalAmountSum = 0;
				$whereClause1[] = 'sqlFunction||sum|ActualMoney|money';
				$objTotalExpenses = getMultiple( 'expense', $whereClause1 );
				if( $objTotalExpenses->getResultCount() > 0 ){
					$result = $objTotalExpenses->varDump();
					if( count( $result ) > 0 ){
						$totalAmountSum = $result[ 0 ][ 'money' ];
					}
				}
				$expenses[] = array(
					'id' => '', 'desc' => 'Total', 'status' => '', 
					'money' => 'Rs. ' . $totalAmountSum . '/-', 'shortDesc' => '',
					'team' => '', 'group' => '', 'creator' => '', 'date' => ''
				);
			}
			/* Paging area  */
			$paging = array();
			$latestPages = $objExpenses->getPaging( 'report/nv/page/');
			$countPages = count( $latestPages );
			for( $i = 0; $i < $countPages; $i++ ) {
				$paging[$i]['number'] = $latestPages[$i]['numbers'];
				$paging[$i]['class'] =  $latestPages[$i]['isActive'] ? 'active' : 'inactive';
				$paging[$i]['link'] = $latestPages[$i]['link'] ? $latestPages[$i]['link'] .( count( $filters ) > 0 ? implode( '/', $filters ) . '/' : '' ) : '';
			}
			$teamExpenses[ 'expenses' ] = $expenses;
			$teamExpenses[ 'paging' ] = $paging;
			return $teamExpenses;
		}catch( Exception $ex ){
			throw $ex;
		}
	}

	/**
	 * get team group expenses report
	 * @return array
	*/
	public static function getTeamGroupExpensesReport( $teamId, $members ){
		$loginUsrId = Login::checkLoginStatus() == Login::USER_LOGGED_IN ? Login::getUserInfo( 'userId' ) : 0;
		if( $loginUsrId <= 0 ){
			throw new Exception( 'Your login session expired, Please login first!' );
		}
		$expenses = array();
		// where clause
		$whereClause = array( 'status||active', 'processed||N' );
		if( $teamId > 0 && is_numeric( $teamId ) ){
			$whereClause[] = "teamId||$teamId";
		}else{
			return $expenses;
		}

		$objTeam = getMultiple( 'team', "teamId||$teamId" );
		if( $objTeam->getResultCount() == 0 ){
			return $expenses;
		}

		$objTeamGroupChk = false;
		if( count( $members ) > 1 ){
			// make array as a string
			$membersStr = implode( ',', $members );
			$totalMembers = count( $members );
			// check if group exist or not else create the team group
			$objTeamGroupChk = getMultiple( 'group', "members||$membersStr", 
				"membersCount||$totalMembers", "teamId||$teamId", 'status||active' );
			if( $objTeamGroupChk->getResultCount() <= 0 ){
				return $expenses;
			}
			$groupId = $objTeamGroupChk->getGroupId();
			// check if selected members are team part or not
			foreach( $members as $member ){
				$teamMemberChkObj = getMultiple( 'teamMember', "userId||$member", 
				"teamId||$teamId", 'status||active', 'joined||Y', 'count||Y' );
				if( $teamMemberChkObj->getTotalCount() == 0 ){
					throw new Exception( "You can't add this expense as amout spend by member is not active or joined team yet !" );
				}
			}
			$whereClause[] = "groupId||$groupId";
		}else{
			return $expenses;
		}

		try{
			$objTeamGroupMembers = getMultiple( 'groupMember', "teamId||$teamId", "groupId||$groupId", 'quantity||500' );
			foreach( $objTeamGroupMembers() as $i => $objGroupMember ){
				$userId = $objGroupMember->getUserId();
				$objUser = getSingle( 'user', $userId );
				if( $objUser->getResultCount() == 0 ){
					continue;
				}
				$expenses[] = array(
					'user' => $objUser->getName(), 
					'operator' => $objGroupMember->getOperator() == 'plus' ? '' : '-',
					'money' => round( $objGroupMember->getMoney(), 2 ) . '/-'
				);
			}
			return $expenses;
		}catch( Exception $ex ){
			throw $ex;
		}
	}

}
